// currencyConverter.ts

// 缓存条目接口
interface CacheEntry {
  rate: number;
  timestamp: number;
}

// 缓存信息接口
interface CacheInfoEntry {
  key: string;
  rate: number;
  age: string;
  expiresIn: string;
}

// 缓存信息接口
interface CacheInfo {
  size: number;
  entries: CacheInfoEntry[];
}

// API提供商类型
type ApiProvider = "frankfurter" | "exchangerate";

// API响应接口
interface FrankfurterResponse {
  rates: Record<string, number>;
  base: string;
  date: string;
}

interface ExchangeRateResponse {
  rates: Record<string, number>;
  base: string;
  date: string;
}

class CurrencyConverter {
  private apiProvider: ApiProvider;
  private cache: Map<string, CacheEntry>;
  private readonly CACHE_DURATION: number = 5 * 60 * 1000; // 5分钟缓存时间

  constructor(apiProvider: ApiProvider = "frankfurter") {
    this.apiProvider = apiProvider;
    this.cache = new Map();
  }

  // 生成缓存键
  private getCacheKey(fromCurrency: string, toCurrency: string): string {
    return `${fromCurrency.toUpperCase()}_${toCurrency.toUpperCase()}`;
  }

  // 检查缓存是否有效
  private isValidCache(cacheEntry: CacheEntry | undefined): boolean {
    return (
      !!cacheEntry && Date.now() - cacheEntry.timestamp < this.CACHE_DURATION
    );
  }

  // 获取缓存数据
  private getFromCache(
    fromCurrency: string,
    toCurrency: string
  ): number | null {
    const cacheKey = this.getCacheKey(fromCurrency, toCurrency);
    const cacheEntry = this.cache.get(cacheKey);

    if (this.isValidCache(cacheEntry)) {
      return cacheEntry?.rate || 0;
    }

    // 清除过期缓存
    if (cacheEntry) {
      this.cache.delete(cacheKey);
    }

    return null;
  }

  // 保存到缓存
  private saveToCache(
    fromCurrency: string,
    toCurrency: string,
    rate: number
  ): void {
    const cacheKey = this.getCacheKey(fromCurrency, toCurrency);
    this.cache.set(cacheKey, {
      rate: rate,
      timestamp: Date.now(),
    });
  }

  // 获取汇率数据
  private async fetchExchangeRate(
    fromCurrency: string,
    toCurrency: string
  ): Promise<number> {
    const currencies = [fromCurrency, toCurrency].map((c) => c.toUpperCase());

    try {
      let rate: number;

      if (this.apiProvider === "frankfurter") {
        const response = await fetch(
          `https://api.frankfurter.app/latest?from=${currencies[0]}&to=${currencies[1]}`
        );

        if (!response.ok) {
          throw new Error(`HTTP错误: ${response.status}`);
        }

        const data: FrankfurterResponse = await response.json();
        rate = data.rates[currencies[1]];
      } else {
        const response = await fetch(
          `https://api.exchangerate-api.com/v4/latest/${currencies[0]}`
        );

        if (!response.ok) {
          throw new Error(`HTTP错误: ${response.status}`);
        }

        const data: ExchangeRateResponse = await response.json();
        rate = data.rates[currencies[1]];
      }

      if (!rate) {
        throw new Error("无法获取汇率数据");
      }

      return rate;
    } catch (error) {
      console.error("获取汇率数据失败:", error);
      throw new Error(
        `获取汇率失败: ${error instanceof Error ? error.message : "未知错误"}`
      );
    }
  }

  async convert(
    amount: number,
    fromCurrency: string,
    toCurrency: string
  ): Promise<number> {
    const currencies = [fromCurrency, toCurrency].map((c) => c.toUpperCase());

    // 如果是相同货币，直接返回原金额
    if (currencies[0] === currencies[1]) {
      return parseFloat(amount.toFixed(2));
    }

    try {
      // 先检查缓存
      const cachedRate = this.getFromCache(currencies[0], currencies[1]);
      let rate: number;

      if (cachedRate !== null) {
        rate = cachedRate;
      } else {
        console.log("发起API请求");
        rate = await this.fetchExchangeRate(currencies[0], currencies[1]);

        // 保存到缓存
        this.saveToCache(currencies[0], currencies[1], rate);
      }

      return parseFloat((amount * rate).toFixed(2));
    } catch (error) {
      console.error("汇率转换错误:", error);
      throw new Error(
        `汇率转换失败: ${error instanceof Error ? error.message : "未知错误"}`
      );
    }
  }

  // 清空缓存
  clearCache(): void {
    this.cache.clear();
    console.log("缓存已清空");
  }

  // 获取缓存信息
  getCacheInfo(): CacheInfo {
    const now = Date.now();
    const cacheEntries: CacheInfoEntry[] = Array.from(this.cache.entries()).map(
      ([key, value]) => {
        const age = Math.floor((now - value.timestamp) / 1000);
        const expiresIn = Math.max(0, this.CACHE_DURATION / 1000 - age);
        return {
          key,
          rate: value.rate,
          age: `${age}秒`,
          expiresIn: `${expiresIn}秒`,
        };
      }
    );

    return {
      size: this.cache.size,
      entries: cacheEntries,
    };
  }

  // 获取当前API提供商
  getApiProvider(): ApiProvider {
    return this.apiProvider;
  }

  // 设置API提供商
  setApiProvider(provider: ApiProvider): void {
    this.apiProvider = provider;
  }

  // 获取缓存大小
  getCacheSize(): number {
    return this.cache.size;
  }
}

export default CurrencyConverter;
export type { ApiProvider, CacheInfo, CacheInfoEntry };
